package com.zmm.study.order.listener;

import com.rabbitmq.client.Channel;
import com.zmm.study.order.service.OrderService;
import com.zmm.study.order.ware.StockLockedTo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @author 900045
 * @description:
 * @name StockReleaseListener
 * @date By 2021-10-20 10:28:05
 */
@Slf4j
@RabbitListener(queues = "stock.release.stock.queue")
@Service
public class StockReleaseListener {
	
	@Resource
	private OrderService orderService;


	/**
	 * 1.库存自动解锁
	 * 		下订单成功,库存锁定成功,其它的业务调用失败,导致订单回滚.之前锁定的库存也要解锁
	 * 	
	 * 2.订单失败
	 * 		锁库存失败
	 * 	
	 * 	只要解锁库存的消息失败  一定要告诉服务 此次解锁失败 要重试
	 * 	
	 * 	接受延时队列 【LOCK_STOCK】
	 * 	监听队列 		order.delay.queue		/ stock.release.stock.queue
	 * 	Binding
	 * 	routingKey		stock.locked			/ stock.release.#
	 * 	exchange		stock-event-exchange	/ stock-event-exchange
	 * @author: 900045
	 * @date: 2021-10-20 11:45:32
	 * @throws 
	 * @param stockLockedTo: 
	 * @param message: 
	 * @param channel: 
	 * @return: void
	 **/
	@RabbitHandler
	public void handleOrderCloseRelease(StockLockedTo stockLockedTo, Message message, Channel channel) throws IOException {
		log.error("订单:{}自动关闭,准备解锁库存",stockLockedTo.getTaskId());
		// 只要这个方法不抛异常 即 --> 库存解锁成功
		try {
			orderService.unLockStock(stockLockedTo);
			channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
		} catch (Exception e){
			// 如果有异常抛出 --> 库存解锁失败 拒收消息 将消息重新丢回队列 让别人重新消费
			channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
		}
	}
}
